package control;

import java.beans.PropertyVetoException;
import java.util.Locale;

import javax.speech.AudioException;
import javax.speech.Central;
import javax.speech.EngineException;
import javax.speech.EngineList;
import javax.speech.EngineStateError;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;

public class JavaSpeech {
	private SynthesizerModeDesc desc;
	private Synthesizer synthesizer;

	public JavaSpeech() throws Exception {
		
		listAllVoices("general");

		desc = new SynthesizerModeDesc(null,
				"general",
				Locale.US,
				null,
				null);
		try {
			synthesizer = Central.createSynthesizer(desc);
		} catch (IllegalArgumentException e) {
			throw new Exception("Init Error");
		} catch (EngineException e) {
			throw new Exception("Init Error");
		}

		if (synthesizer == null) {
			throw new Exception("No Syntetize error");
		} else {
			try {
				synthesizer.allocate();
				synthesizer.resume();
				synthesizer.getSynthesizerProperties().setVoice(new Voice());
				synthesizer.getSynthesizerProperties().setSpeakingRate(100);
				System.out.println("getPitch : " + synthesizer.getSynthesizerProperties().getPitch());
				System.out.println("getPitchRange : " + synthesizer.getSynthesizerProperties().getPitchRange());
				System.out.println("getSpeakingRate : " + synthesizer.getSynthesizerProperties().getSpeakingRate());
			} catch (EngineException e) {
				throw new Exception("Init Error");
			} catch (EngineStateError e) {
				throw new Exception("Init Error");
			} catch (IllegalArgumentException e) {
				throw new Exception("Init Error");
			} catch (PropertyVetoException e) {
				throw new Exception("Init Error");
			} catch (AudioException e) {
				throw new Exception("Init Error");
			}
		}
	}
	
	public void say(String text) {
		text = text.replaceAll(Type.PES_1, "first person");
		text = text.replaceAll(Type.PES_2, "second person");
		text = text.replaceAll(Type.PES_3, "third person");
		text = text.replaceAll(TypeFilter.SING, "singular");
		text = text.replaceAll(TypeFilter.PLURAL, "plural");
		text = text.replaceAll(Type.FEMININO, "female");
		text = text.replaceAll(Type.MASCULINO, "male");
		text = text.replaceAll(Type.VERB, "verbo");
		
		synthesizer.speakPlainText(text, null);
		/*try {
			synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
	}

	public void exit() {
		try {
			synthesizer.deallocate();
		} catch (EngineException e) {
			e.printStackTrace();
		} catch (EngineStateError e) {
			e.printStackTrace();
		}
	}
	
	public void listAllVoices(String modeName) {

		System.out.println();
		System.out.println("All " + modeName
				+ " Mode JSAPI Synthesizers and Voices:");

		/*
		 * Create a template that tells JSAPI what kind of speech synthesizer we
		 * are interested in. In this case, we're just looking for a general
		 * domain synthesizer for US English.
		 */
		SynthesizerModeDesc required = new SynthesizerModeDesc(null, // engine
				// name
				modeName, // mode name
				Locale.US, // locale
				null, // running
				null); // voices

		/*
		 * Contact the primary entry point for JSAPI, which is the Central
		 * class, to discover what synthesizers are available that match the
		 * template we defined above.
		 */

		EngineList engineList = Central.availableSynthesizers(required);
		for (int i = 0; i < engineList.size(); i++) {

			SynthesizerModeDesc desc = (SynthesizerModeDesc) engineList.get(i);
			System.out.println("    " + desc.getEngineName() + " (mode="
					+ desc.getModeName() + ", locale=" + desc.getLocale()
					+ "):");
			Voice[] voices = desc.getVoices();
			for (int j = 0; j < voices.length; j++) {
				System.out.println("        " + voices[j].getName());
			}
		}
	}

}
